package br.uff.javaavancado.service;

import br.uff.javaavancado.controletransacao.Transacional;
import br.uff.javaavancado.dao.ItemDAO;
import br.uff.javaavancado.dao.PedidoDAO;
import br.uff.javaavancado.dao.ProdutoDAO;
import br.uff.javaavancado.dao.controle.FabricaDeDao;
import br.uff.javaavancado.dao.impl.ItemDAOImpl;
import br.uff.javaavancado.dao.impl.PedidoDAOImpl;
import br.uff.javaavancado.dao.impl.ProdutoDAOImpl;
import br.uff.javaavancado.exception.ObjetoNaoEncontradoException;
import br.uff.javaavancado.modelos.ItemPedido;
import br.uff.javaavancado.modelos.Pedido;
import br.uff.javaavancado.modelos.Produto;

public class PedidoService extends BaseService implements Service, java.io.Serializable {

    private static final long serialVersionUID = 1L;
    private PedidoDAO pedidoDAO;
    private ProdutoDAO produtoDAO;
    private ItemDAO itemDAO;

    public PedidoService() {
        super(PedidoService.class);
        try {
            pedidoDAO = FabricaDeDao.getDao(PedidoDAOImpl.class, Pedido.class);
            produtoDAO = FabricaDeDao.getDao(ProdutoDAOImpl.class, Produto.class);
            itemDAO = FabricaDeDao.getDao(ItemDAOImpl.class, ItemPedido.class);
        } catch (Throwable e) {
            e.printStackTrace();
//            logger.error(e);

        }
    }

    @Transacional
    public ItemPedido adicionaItem(Produto pro, Pedido ped) {
        try {
            pro = produtoDAO.getPorIdComLock(pro.getId());
//            pro = produtoDAO.getPorId(pro.getId());
            long estoque = pro.getEstoque();

            if (estoque > 0) {
                pro.setEstoque(--estoque);
            } else {
                return null;
            }
            
            produtoDAO.altera(pro);
            
            if (ped.getId() == null) {
                pedidoDAO.inclui(ped);
            } else {
                pedidoDAO.altera(ped);
            }
            
            ItemPedido it;
            try{
                it = itemDAO.getItemPedido(ped, pro);
            }catch (ObjetoNaoEncontradoException ex) {
                it = new ItemPedido();
                it.setPedido(ped);
                it.setProduto(pro);
            }
            
            int qtd = it.getQtd();
            it.setQtd(++qtd);
            it.setValor(pro.getPreco());
            
            if (it.getId() == null) {
                itemDAO.inclui(it);
            } else {
                itemDAO.altera(it);
            }
            
            return it;
        } catch (ObjetoNaoEncontradoException ex) {
            return null;
        } catch (Throwable t) {
            return null;
        }

    }

    @Transacional
    public void fecharCompra(Pedido pedido) {
        pedido.setFechado(true);
        pedidoDAO.altera(pedido);
        
    }

    @Transacional
    public ItemPedido removeItem(Produto pro, Pedido ped) {
        try {
            pro = produtoDAO.getPorIdComLock(pro.getId());
//            pro = produtoDAO.getPorId(pro.getId());
            long estoque = pro.getEstoque();
            pro.setEstoque(++estoque);

            ItemPedido it = itemDAO.getItemPedido(ped, pro);
            it = itemDAO.getPorIdComLock(it.getId());
            
            int qtd = it.getQtd();
            it.setQtd(--qtd);
            if (qtd == 0) {
                itemDAO.exclui(it);
            } else {
                itemDAO.altera(it);
            }
           
            produtoDAO.altera(pro);

            return it;
        } catch (ObjetoNaoEncontradoException ex) {
            return null;
        } catch (Throwable t) {
            return null;
        }
    }
}
